<script setup>
import { nextTick, onBeforeMount, onMounted, onUnmounted, ref } from 'vue'
import confetti from 'canvas-confetti'
import { devMode } from './config'

//TODO: 添加一键分享到微信功能，分享分数
const name = ref('anonymous')
const showLeaderboard = ref(false)

//TODO：优化排行榜显示
const baseURL = new URL('https://codeful.cn/')
const apiURL = new URL('/api/leaderboard', baseURL)
const leaderboardData = ref([])
const newHighscoreRef = ref(null)
const props = defineProps(['score', 'maxStreak', 'maxMultiply', 'clickCount'])
const emit = defineEmits(['restart'])
const isLocalHighScore = ref(false)
const isGlobalHighScore = ref(false)
const headingText = ref('')
const headingRef = ref(null)

onBeforeMount(() =>
    initLoad()
)

onUnmounted(() => {
    isGlobalHighScore.value = false
})

const submitName = () => {
    isGlobalHighScore.value = false
    postLeaderboard()

}

async function initLoad() {
    await getLeaderboard()

    if (props.score > leaderboardData.value.at(-1)[2]) {
        showLeaderboard.value = true
        isGlobalHighScore.value = true
        headingText.value = '恭喜上榜!'
        wiggleAnimation(headingRef.value)
    } else {
        headingText.value = '游戏结束'
        postLeaderboard()
    }
}

//排行榜相关函数
async function toggleLeaderboard() {
    showLeaderboard.value = !showLeaderboard.value
    getLeaderboard()
}
async function getLeaderboard() {
    try {
        const res = await fetch(apiURL)
        if (res.ok) {
            leaderboardData.value = await res.json()
            console.log('leaderboard', leaderboardData)
        } else {
            console.log(res.status)
        }
    }
    catch (error) {
        console.log('fail to get leaderboard', error.name)
        throw error
    }
}
async function postLeaderboard() {
    await fetch(apiURL, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            name: name.value,
            score: props.score,
            clicks: props.clickCount
        })
    })
    //刷新排行榜
    await getLeaderboard()
}

const wiggleAnimation = (element) => {
    //先占个位
    const rotation = 0
    element.animate(
        [{ transform: 'rotate(-5deg)' },
        { transform: 'rotate(5deg)' },
        ], { duration: 300, easing: 'ease-in', iterations: Infinity, direction: 'alternate' })
}
//TODO:没搞明白这个z-axis怎么表现的
const depthPushAnimation = (element) => {
    element.animate([
        {
            transform: 'translateZ(0) scale(1)',
            filter: 'blur(100px)'
        },
        {
            transform: 'translateZ(-300px) scale(0.8)',
            filter: 'blur(5px)'
        },
        {
            transform: 'translateZ(0) scale(1)',
            filter: 'blur(0px)'
        }
    ], {
        duration: 1500,
        easing: 'ease'
    })
}
//彩带相关函数
const triggerConfetti = () => {
    triggerRibbons()
}

const triggerRainbowExplosion = () => {
    confetti({
        particleCount: 150,
        spread: 180,
        origin: { y: 0.4 },
        colors: ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff']
    })
}
const triggerRibbons = () => {
    confetti({
        particleCount: 100,
        angle: 60,
        spread: 55,
        origin: { x: 0 },
        colors: ['#bb0000', '#ffffff', '#efe791']
    })

    confetti({
        particleCount: 100,
        angle: 120,
        spread: 55,
        origin: { x: 1 },
        colors: ['#bb0000', '#ffffff']
    })
}

//按钮和页面操作
const clearHighscore = () => {
    localStorage.removeItem('score')
}

const restart = () => {
    emit('restart')
}

//最高分判定和行动
let highScore = parseInt(localStorage.getItem('score'))

//TODO: 优化动画
const newHighScoreAnimation = () => {
    if (newHighscoreRef.value) {
        newHighscoreRef.value.animate([
            { transform: 'scale(3) translateY(100px)' },
            { transform: 'scale(1) translateY(0)' }
        ], {
            duration: 1000,
            iterations: 1,
            easing: 'ease'
        })
    }
}
async function newHighscoreTrigger() {
    if (highScore < props.score || !highScore) {
        triggerConfetti()
        isLocalHighScore.value = true
        highScore = props.score
        localStorage.setItem('score', props.score)
        //NOTE：等待dom加载完成，再执行动画
        await nextTick(() => newHighScoreAnimation())

    }
}


newHighscoreTrigger()

//以下都是为了实现：按下 r键，重新开始
onMounted(() => {
    // 组件挂载后，自动获取焦点
    if (gameoverRef.value) {
        gameoverRef.value.focus()
    }

    depthPushAnimation(headingRef.value)
})

const gameoverRef = ref(null)
</script>


<template>
    <div ref='gameoverRef' tabindex="0" class="gameoverWindow" @keydown.r="restart">
        <h1 ref="headingRef" id="heading">{{ headingText }}</h1>
        <div ref="newHighscoreRef" id="newHighscore" v-if="isLocalHighScore">最好成绩🎉</div>
        <div class="scorePanel" v-show="!showLeaderboard">
            <p id="score" :class="{ highScore: isLocalHighScore }">分数:{{ score }}</p>
            <p>个人最好成绩:{{ highScore }}</p>
            <p id="maxStreak">最大连击数:{{ maxStreak }}</p>
            <p id="maxMultiply">最大倍数:{{ maxMultiply }}</p>
        </div>

        <div class="submitName" v-if="isGlobalHighScore">
            <p>请输入名字</p>
            <input type="text" placeholder="输入你的名字" v-model="name" maxlength="10">
            <button @click="submitName()">提交</button>
        </div>

        <div class="leaderboard" v-show="showLeaderboard">
            <h2 id="leaderboardHeading" v-if="false">排行榜</h2>
            <div class="table-container">
                <table>
                    <thead>
                        <tr>
                            <th>排名</th>
                            <th>玩家</th>
                            <th>分数</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(item, index) in leaderboardData">
                            <td>{{ index + 1 }}</td>
                            <td>{{ item[1] }}</td>
                            <td>{{ item[2] }}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>



        <div class="buttonPanel">
            <button @click='restart' class="restart">重新开始</button>
            <button @click="toggleLeaderboard" v-show="!showLeaderboard">查看排行榜</button>
            <button @click="toggleLeaderboard" v-show="showLeaderboard">关闭排行榜</button>
            <button v-if="devMode" @click="clearHighscore">清除最高分</button>
            <button v-if="devMode" @click="triggerConfetti">canvas-confetti测试</button>
            <button v-if="devMode" @click="newHighScoreAnimation">新高分动画</button>

        </div>
    </div>


</template>

<style scoped>
.submitName {
    display: flex;
    flex-direction: row;
    width: 100%;
    align-items: center;
    justify-content: space-around;
}

.submitName input {
    width: 30vw;
}

:root {
    --heading-delay-time: 1s;
}

.gameoverWindow {
    background-color: #f0d095;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100dvh;
}

button {
    background-color: #fff;
    color: #000;
    padding: 10px 20px;
    border-radius: 5px;
    margin-left: 20px;
}

.scorePanel {
    text-align: center;
    font-size: 10dvw;
    font-weight: 700;
    /* margin: 20px; */
    color: rgb(31, 122, 161);
    animation: fadeInUp 1s ease-in-out forwards;
    animation-delay: var(--heading-delay-time);
    opacity: 0;
}

#heading {
    font-size: 20dvw;
    font-weight: 700;
    animation: ease-in-out var(--heading-delay-time) fadeInUp;
    color: rgb(101, 101, 101);
}

#newHighscore {
    font-size: 10dvw;
    font-weight: 700;
    color: rgb(31, 122, 161);
    opacity: 1;
    animation: big2small 1s ease-in-out forwards;
}

.leaderboard {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 3vh;
}

.table-container {
    border-radius: 20px;
}

.leaderboard table {
    text-align: center;
    width: 90vw;
    border-collapse: collapse;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
}

.leaderboard table th {
    background-color: rgb(80, 117, 210);
    padding: 1.3rem;
    color: #fff;
    font-size: 1.4rem;
}

.leaderboard table tbody {
    background-color: rgb(240, 234, 226);

}


@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes big2small {
    from {
        transform: scale(5), translateY(40px);
    }

    to {
        transform: scale(1), translateY(0);
    }
}

.highScore {
    color: rgb(255, 0, 0);
}
</style>